/*
 * 原型模式本质上说就是对当前数据进行复制。就像变戏法一样，一个鸽子变成了两个鸽子，两个鸽子变成了三个鸽子，
 *
 * 就这么一直变下去。在变的过程中，我们不需要考虑具体的数据类型。为什么呢？
 *
 * 因为不同的数据有自己的复制类型，而且每个复制函数都是虚函数。
 */



typedef struct prototype
{
	struct prototype * (*copy)(struct prototype * pdata);
}prototype;

/* 
 * 假设也有这么一个类型 data_a
 */

prototype data_a = {data_copy_a};

/*
 * 既然上面用到了这个函数，所以我们也要定义啊
 */
struct prototype * data_copy_a(struct prototype * pdata)
{
	struct prototype * presult = (struct prototype *) malloc(sizeof(struct prototype));
	assert(NULL != presult);
	memmove(presult, pdata, sizeof(struct prototype));
	return presult;
}

struct prototype * clone(struct prototype * pdata)
{
	return pdata->copy(pdata);
}


/////////

typedef void * (fun_clone*)();

// 定义Clonable接口
struct cloneable 
{
	fun_clone copy;
};

// Person类扩展Clonable接口   
struct person{  
    struct cloneable base;  
    unsigned int age;  
};  

struct cloneable * cloneperson()
{
	return (struct cloneable *) malloc(sizeof(person));
}

// 创建Clonable对象的Factory  
struct cloneable * clonable_factory(struct cloneable * able)
{
	if (0 == able)
		return 0;
	return able->copy();
}

// 用法 
{
	person p;
	p.base.copy = cloneperson;

	person * anotherperson = 0;
	anotherperson = (person*)clonable_factory(&p);
}

